package com.heima.mobile.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.heima.dto.DishDto;
import com.heima.pojo.Dish;
import com.heima.service.DishService;
import com.heima.vo.DishVo;
import com.heima.vo.Result;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @author itheima
 * @since 2022-11-30
 */
@RestController
@RequestMapping("/dish")
public class DishController {

    @Autowired
    private DishService dishService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @PutMapping
    @CacheEvict(value = "dishList", allEntries = true)
    public Result updateDish(@RequestBody DishDto dishDto) {

        // 1. MySQl更新Dish的数据
        Boolean updateResult = dishService.modifyDish(dishDto);

        // 2. 对应更新缓存(1.删除指定缓存，2.找到我更新的那个缓存，并且修改）
        String cacheKey = "dishList" + dishDto.getCategoryId() + "," + dishDto.getStatus() + ",1,10";
        // redisTemplate.delete(cacheKey);

        // 查询缓存数据
        String cache = redisTemplate.opsForValue().get(cacheKey);

        // 将缓存转成java可以处理的对象
        // 1. 找到我改了哪条
        // 2 把我改的哪条数据，覆盖一下
        // 3. 转回JSON形式
        // 4. 协回Redis
        List<DishVo> vos = JSON.parseArray(cache, DishVo.class);
        if (!CollectionUtil.isEmpty(vos)) {
            for (DishVo vo : vos) {
                if (vo == null) {
                    continue;
                }

                if (dishDto.getId().equals(vo.getId())) {
                    // 当前这条数据，是我想要的
                    // 于是直接把它覆盖掉
                    BeanUtils.copyProperties(dishDto, vo);
                }
            }
        }

        String newCache = JSON.toJSONString(vos);

        redisTemplate.opsForValue().set(cacheKey, newCache);

        // 3. 返回结果
        return new Result(200, "", null);
    }

    @GetMapping("/list")
    //@Cacheable(value = "dishList", key = "#categoryId + '|' + #status + '|' + #page + '|' + #pageSize")
    public Result getDishList(@RequestParam("categoryId") String categoryId,
                              @RequestParam("status") Integer status,
                              @RequestParam(value = "page", defaultValue = "1") Integer page,
                              @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {

        // 1. 检查用户想要的数据，是否存在于Redis
        // cacheKey 代表，当前接口对应的数据，所存储的位置
        // 命名：接口名称 + 接口方法所有入参 组合在一起形成一个字符串
        // dishList1,1,1,10 -> 查询分类1下面，状态为开启，第一页的10条数据
        // dishList1,1,2,10 -> 查询分类1下面，状态为开启，第二页的10条数据
//        String cacheKey = "dishList" + categoryId + "," + status + "," + page + "," + pageSize;
//        String cache = redisTemplate.opsForValue().get(cacheKey);
//
//        // 2. 如果存在 -> 直接从redis读取出来 -> 返回
//        if (!StringUtils.isEmpty(cache)) {
//            // 需要把Redis中取出的字符串 转成MySQL中查询出来的数据的类型
//            List<DishVo> vos = JSON.parseArray(cache, DishVo.class);
//            return new Result(200, "", vos);
//        }

        // 3. 如果不存在 -> 查询数据库
        List<DishVo> dishList = dishService.getDishListPlus(categoryId, status, page, pageSize);

        ArrayList list = new ArrayList();

        // 4. 从数据库查到的数据，写一份到Redis中
//        redisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(dishList));

        // 5. 返回给前端
        return new Result(200, "", dishList);
    }

    @GetMapping("/byId")
    @Cacheable(value = "dish", key = "#dishId")
    public Result getOneById(@RequestParam String dishId) {
        Dish dish = dishService.getById(dishId);
        return new Result(200, "", dish);
    }

    /**
     * CacheEvict注解测试
     *
     * @param dishDto
     * @return
     */
    @PutMapping("/fast")
    //@CacheEvict(value = "dishList", key = "#dishDto.categoryId +'|'+ #dishDto.status", allEntries = true)
    @CachePut(value = "dish", key = "#dishDto.id")
    public Result fastModify(@RequestBody DishDto dishDto) {
        // 1. MySQl更新Dish的数据
        Boolean updateResult = dishService.modifyDish(dishDto);

        Dish dish = dishService.getById(dishDto.getId());

        // 3. 返回结果
        return new Result(200, "哈哈我是CachePut的返回值", dish);
    }
}
